﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace NewCROStarter
{
    public partial class Config : Form
    {
        public Config()
        {
            InitializeComponent();
        }

        //config.xml文件位置
        private string confpath;
        //储存补丁信息，格式是：文件名 是否启用（0/1）
        List<string[]> patchs;

        private void Config_Load(object sender, EventArgs e)
        {
            //生成config.xml文件路径
            confpath = System.Threading.Thread.GetDomain().BaseDirectory + @"NewCROStarter\";
            this.Activate();
            //从xml载入配置
            Load_Config();
        }

        //指示该窗体关闭时的返回值，=OK为继续启动RO客户端，=Cancel为关闭整个程序
        DialogResult ExitCode=DialogResult.Cancel;

        private void Load_Config()
        {
            //从xml读取
            string starterconfpath = confpath + "Config.xml";
            XmlDocument xd = new XmlDocument();
            xd.Load(starterconfpath);
            XmlNodeList xlist = xd.SelectSingleNode("NewRoStarterConfig").ChildNodes;
            foreach (XmlNode xnode in xlist)
            {
                XmlElement xelement = (XmlElement)xnode;
                if (xelement.GetAttribute("EnableTool") == "1") cb_EnableTool.Checked = true; else cb_EnableTool.Checked = false;
                if (xelement.GetAttribute("AutoCloseTool") == "1") cb_AutoCloseTool.Checked = true; else cb_AutoCloseTool.Checked = false;
                if (xelement.GetAttribute("AutoResizeWin") == "1") cb_AutoResizeWin.Checked = true; else cb_AutoResizeWin.Checked = false;
                cb_RoWinSize.Text = xelement.GetAttribute("RoWinSize");
            }
        }

        private void Save_Config()
        {
            string starterconfpath = confpath + "Config.xml";
            XmlTextWriter xw = new XmlTextWriter(starterconfpath, Encoding.UTF8);
            xw.Formatting = Formatting.Indented;
            xw.WriteStartDocument();
            xw.WriteStartElement("NewRoStarterConfig");
            xw.WriteStartElement("Node");
            if (cb_EnableTool.Checked) xw.WriteAttributeString("EnableTool", "1"); else xw.WriteAttributeString("EnableTool", "0");
            if (cb_AutoCloseTool.Checked) xw.WriteAttributeString("AutoCloseTool", "1"); else xw.WriteAttributeString("AutoCloseTool", "0");
            if (cb_AutoResizeWin.Checked) xw.WriteAttributeString("AutoResizeWin", "1"); else xw.WriteAttributeString("AutoResizeWin", "0");
            xw.WriteAttributeString("RoWinSize", cb_RoWinSize.Text);
            xw.WriteEndElement();
            xw.WriteEndElement();
            xw.Close();
        }

        private void btn_SaveExit_Click(object sender, EventArgs e)
        {
            Save_Config();
            ExitCode = DialogResult.Cancel;
            this.DialogResult = ExitCode;
            this.Close();
        }

        private void btn_SaveRunRo_Click(object sender, EventArgs e)
        {
            Save_Config();
            ExitCode = DialogResult.OK;
            this.DialogResult = ExitCode;
            this.Close();
        }

        private void Config_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.DialogResult = ExitCode;
        }

        //取消更改，从xml中读取信息并覆盖gui
        private void btn_ReloadConfig_Click(object sender, EventArgs e)
        {
            Load_Config();
        }

        //扫描目录中的zip文件，放入数组中，设置启用选项为0（不启用）
        //读取patch.xml，将对应已启用的zip文件在数组中标记为1
        private void tn_rescanPatch_Click(object sender, EventArgs e)
        {
            patchs = new List<string[]>();
            string patchconfpath = confpath + "Patch.xml";
            string patchpath = confpath + @"\clientpatch\";
            //列出patchpath中的所有zip

            foreach (string file in Directory.GetFiles(patchpath, "*.zip", SearchOption.TopDirectoryOnly))
            {
                patchs.Add(new string[] { file.ToLower().Remove(0,file.LastIndexOf('\\')+1), "0" });
            }
            //从xml读取
            XmlDocument xd = new XmlDocument();
            xd.Load(patchconfpath);
            XmlNodeList xlist = xd.SelectSingleNode("NewRoStarterConfig").ChildNodes;
            foreach (XmlNode xnode in xlist)
            {
                XmlElement xelement = (XmlElement)xnode;
                foreach (string[] tmparray in patchs)
                {
                    if (tmparray[0] == xelement.GetAttribute("PatchName")) tmparray[1] = xelement.GetAttribute("Enabled");
                }
            }
            //显示
            clb_patches.Items.Clear();
            foreach (string[] tmparray in patchs)
            {
                bool ischecked = false;
                if (tmparray[1] == "1") ischecked = true;
                clb_patches.Items.Add(tmparray[0], ischecked);
            }
            //启用保存功能
            btn_savePatchConfig.Enabled = true;
            btn_ApplyPatchs.Enabled = true;
        }

        //从checkboxlist中读取信息，保存配置文件
        private void btn_savePatchConfig_Click(object sender, EventArgs e)
        {
            string patchconfpath = confpath + "Patch.xml";
            XmlTextWriter xw = new XmlTextWriter(patchconfpath, Encoding.UTF8);
            xw.Formatting = Formatting.Indented;
            xw.WriteStartDocument();
            xw.WriteStartElement("NewRoStarterConfig");
            for (int i = 0; i < clb_patches.Items.Count; i++)
            {
                xw.WriteStartElement("Node");
                xw.WriteAttributeString("PatchName",clb_patches.Items[i].ToString());
                if (clb_patches.GetItemChecked(i))
                {
                    xw.WriteAttributeString("Enabled", "1");
                }
                else 
                {
                    xw.WriteAttributeString("Enabled", "0");
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();
            xw.Close();
        }

        //确认清空data目录，从配置文件取得=1的补丁，将对应的zip解压缩到data
        private void btn_ApplyPatchs_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("此操作将删除所有补丁并应用新的设置，是否确认？", "应用补丁设置", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
            if (dr == DialogResult.No) return;
            //停用按钮
            btn_ApplyPatchs.Enabled = false;
            btn_rescanPatch.Enabled = false;
            btn_savePatchConfig.Enabled = false;

            //补丁zip存放位置
            string patchpath = confpath + @"\clientpatch\";
            //补丁释放位置
            string destpath = System.Threading.Thread.GetDomain().BaseDirectory;
            //删除data文件夹
            string datadir = System.Threading.Thread.GetDomain().BaseDirectory + @"data";
            if (Directory.Exists(datadir))
            {
                try { Directory.Delete(datadir, true); }
                catch (Exception ex) 
                {
                    MessageBox.Show("后续操作已取消，原因是：\r\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    //启用按钮
                    btn_ApplyPatchs.Enabled = true;
                    btn_rescanPatch.Enabled = true;
                    btn_savePatchConfig.Enabled = true;
                    return;
                }
            }
            //循环checkboxlist，取得已勾选的数量，设置progressbar
            int counter=0;
            for (int i = 0; i < clb_patches.Items.Count; i++)
            {
                if (clb_patches.GetItemChecked(i))
                {
                    counter++;
                }
            }
            progressBar1.Maximum = counter;
            progressBar1.Value = 0;
            //从checkboxlist中读取已选的项目，解压缩zip到.\
            for (int i = 0; i < clb_patches.Items.Count; i++)
            {
                if (clb_patches.GetItemChecked(i))
                {
                    UnZipFile(patchpath + clb_patches.Items[i].ToString(), destpath);
                    progressBar1.PerformStep();
                    this.Update();
                }
            }
            //启用按钮
            btn_ApplyPatchs.Enabled = true;
            btn_rescanPatch.Enabled = true;
            btn_savePatchConfig.Enabled = true;
        }

        //解压缩文件
        private void UnZipFile(string sourcefile, string destpath)
        {
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourcefile)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    Console.WriteLine(theEntry.Name);

                    string directoryName = destpath + Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    // create directory
                    if (directoryName.Length > 0)
                    {
                        Directory.CreateDirectory(directoryName);
                    }

                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(theEntry.Name))
                        {

                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        //获得zip文件注释
        private string GetZipFileComment(string sourcefile)
        {
            ZipFile zf = new ZipFile(sourcefile);
            string result = zf.ZipFileComment;
            zf.Close();
            return result;
        }

        //全选
        private void btn_selectAllPatchs_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < clb_patches.Items.Count; i++)
            {
                clb_patches.SetItemCheckState(i, CheckState.Checked);
            }
        }

        //反选
        private void btn_revSelectPatchs_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < clb_patches.Items.Count; i++)
            {
                if (clb_patches.GetItemChecked(i))
                {
                    clb_patches.SetItemChecked(i, false);
                }
                else
                {
                    clb_patches.SetItemChecked(i, true);
                }
            }
        }

        private void clb_patches_SelectedIndexChanged(object sender, EventArgs e)
        {
            string patchpath = confpath + @"\clientpatch\";
            ListBox tempbox = (ListBox)sender;
            patchpath = patchpath + tempbox.Text;
            tb_PatchComment.Text = GetZipFileComment(patchpath);
        }
    }
}
